<?php

namespace App\Admin\Controllers;

use App\Admin\Extensions\Tools\BannedAction;
use App\Admin\Extensions\Tools\PlayerAction;
use App\Admin\Extensions\Tools\PlayerBanAction;
use App\Http\Controllers\Controller;
use App\Models\Base\Charge;
use App\Models\Base\Item;
use App\Models\Base\ServerList;
use App\Models\Base\StatEvent;
use App\Models\GameLog\LogExpChange;
use App\Models\GameLog\LogItem;
use App\Models\GameLog\LogMoneyChange;
use App\Models\GameLog\LogPlayerMail;
use App\Models\Game\Items;
use App\Models\Game\PlayerGamedata;
use App\Models\Login\Account;
use App\Service\ChannelService;
use App\Service\PlayerService;
use App\Service\RequestService;
use App\Service\ServerService;
use Carbon\Carbon;
use Encore\Admin\Facades\Admin;
use Encore\Admin\Grid;
use Encore\Admin\Layout\Content;
use Encore\Admin\Widgets\Table;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Input;
use Illuminate\Support\Facades\Log;

/**
 * 游戏玩家相关.
 */
class PlayerController extends Controller {
	protected $server_id;
	protected $ip;

	public function __construct(Request $request) {
		if (Input::get('serverid')) {
			$this->server_id = Input::get('serverid');
		} else {
			$all = ServerList::all();
			$this->server_id = $all[0]->server_id;
		}
		setDB($this->server_id);
		$this->ip = $request->getClientIp();
	}

	/**
	 * [role 玩家角色].
	 *
	 * @Author   王文凡
	 * @DateTime 2018-02-27
	 *
	 * @version  1.0
	 *
	 * @return object
	 */
	public function role() {
		return Admin::content(function (Content $content) {
			$content->header(trans('game.player_related'));
			$content->description(trans('admin.list'));
			$content->body($this->roleGrid()->render());
			$options = [
				0 => trans('game.email_info'),
				1 => trans('game.bag'),
				2 => trans('game.warehouse'),
				3 => trans('game.equipment'),
				4 => trans('game.props_change'),
				5 => trans('game.physical_changes'),
				6 => trans('game.exp_change'),
				8 => trans('game.treasure'),
				13 => trans('game.wings'),
			];
			$content->row(view('admin.users.view', compact('options')));
		});
	}

	/**
	 * [roleGrid 显示角色列表].
	 *
	 * @Author   王文凡
	 * @DateTime 2018-02-27
	 *
	 * @version  1.0
	 *
	 * @return object
	 */
	protected function roleGrid() {
		$grid = Admin::grid(PlayerGamedata::class, function (Grid $grid) {
			$server_id = $this->server_id;
			$grid->model()->orderBy('registerTime', 'desc');
			$grid->id(trans('game.role_id'));
			$grid->name(trans('game.role_name'));
			$grid->column(trans('game.server_name'))->display(function () use ($server_id) {
				return ServerService::getReServerName($server_id);
			});
			$grid->registerTime(trans('game.reg_date'))->display(function ($registerTime) {
				return date('Y-m-d H:i:s', $registerTime);
			});

			$grid->totaltreasure(trans('game.amount'))->display(function ($total) {
				$money = $total / config('game.topUp');

				return '<a target="_blank" href="' . route('order.index') . '?player_id=' . $this->id . '">' . $money . '</a>';
			})->sortable();

			$grid->fightingCapacity(trans('game.fight_power'))->sortable();
			$grid->level(trans('game.level'))->sortable();
			$grid->column(trans('game.vip_lv'))->display(function () {
				return getVIP($this->totaltreasure);
			});

			$grid->treasure(trans('game.crystal_number'))->display(function ($treasure) use ($server_id) {
				return '<a target="_blank" href="' . route('player.record') . '?player_id=' . $this->id . '&type=11&serverid=' . $server_id . ' ">' . $treasure . '</a>';
			});

			$grid->coin(trans('game.coin'))->sortable()->display(function ($coin) use ($server_id) {
				return '<a target="_blank" href="' . route('player.record') . '?player_id=' . $this->id . '&type=9&serverid=' . $server_id . ' ">' . $coin . '</a>';
			});
			$grid->gold(trans('game.gold'))->sortable()->display(function ($gold) use ($server_id) {
				return '<a target="_blank" href="' . route('player.record') . '?player_id=' . $this->id . '&type=10&serverid=' . $server_id . ' ">' . $gold . '</a>';
			});

			$grid->stone(trans('game.stone'))->display(function ($stone) use ($server_id) {
				return '<a target="_blank" href="' . route('player.record') . '?player_id=' . $this->id . '&type=12&serverid=' . $server_id . ' ">' . $stone . '</a>';
			})->sortable();

			$grid->lastOnlineTime(trans('game.last_login_time'))->display(function ($time) {
				return date('Y-m-d H:i:s', $time);
			});
			$grid->isOnline(trans('game.status'))->display(function ($isOnline) {
				return $isOnline ? trans('game.online') : trans('game.not_online');
			})->sortable();
			$grid->isDelete(trans('game.whether_lock'))->display(function ($isDelete) {
				return $isDelete ? trans('game.yes') : trans('game.no');
			});

			$grid->disableCreateButton();

			//角色信息按钮
			$grid->actions(function ($actions) use ($grid, $server_id) {
				$actions->disableEdit();
				$actions->disableDelete();
				$actions->prepend('<a href="" class="btn btn-xs btn-primary gameuser-model" data-id="' . $actions->getKey() . '" data-toggle="modal" data-name="' . $actions->row->name . '"  onclick="playerView(this)" data-name="' . $actions->row->name . '" >'.trans('game.more').'</a>');
				$actions->prepend('<a href="' . route('player.view') . '?serverid=' . $server_id . '&player_id=' . $actions->getKey() . '" class="btn btn-xs btn-primary" >'.trans('game.detail').'</a>&nbsp;&nbsp;');
			});

			// 角色信息模态框
			$grid->tools(function ($tools) {
				$tools->batch(function ($batch) {
					$batch->disableDelete();
					$batch->add(trans('game.kick_off'), new PlayerAction(1));
					$batch->add(trans('game.seal_role'), new PlayerBanAction());
					$batch->add(trans('game.banned'), new BannedAction());
				});
			});

			// 字段过滤器
			$grid->filter(function ($filter) {
				$filter->disableIdFilter();
				$filter->setNotWhere(['serverid']);
				$filter->equal('channelId', trans('game.channel'))->select(ChannelService::getChannelNameNo());
				$filter->where(function ($query) {
				}, trans('game.server_name'), 'serverid')->select(ServerList::all()->pluck('name', 'server_id'));

				$filter->like('name', trans('game.role_name'));
			});
		});

		return $grid;
	}

	public function view() {
		return Admin::content(function (Content $content) {
			$player_id = Input::get('player_id');
			$data = PlayerGamedata::find($player_id);
			$content->header(trans('game.player_related'));
			$content->description('玩家角色详情');
			$account = Account::find($data->userId);
			$platform = Charge::where('channel_no', $account->channelId)->first();
			$content->body(view('admin.player.view', ['data' => $data, 'account' => $account, 'platform' => $platform]));
		});
	}

	/**
	 * [kicking 踢用户下线].
	 *
	 * @Author   王文凡
	 * @DateTime 2018-04-08
	 *
	 * @version  1.0
	 *
	 * @return
	 */
	public function kicking(Request $request) {
		$post = $request->post();
		$ids = $post['ids'];
		$status = $post['status'];
		$num = 0;
		$now = Carbon::now()->toDateTimeString();
		$admin_name = \Auth::guard('admin')->user()->name;
		foreach ($ids as $id) {
			$player = PlayerGamedata::find($id);
			$role_name = $player->name;
			$ret = RequestService::playerKickOff($this->server_id, $role_name);
			if (!$ret) {
				++$num;
				Log::error('踢用户下线失败:', $post);
			} else {
				DB::table('log_kicks')->insert([
					'server_id' => $this->server_id,
					'player_id' => "{$id}",
					'player_name' => $role_name,
					'admin_name' => $admin_name,
					'client_ip' => $this->ip,
					'created_at' => $now,
					'updated_at' => $now,
				]);
			}
		}

		return ['status' => 0, 'message' => '执行成功!' . $num . '个失败'];
	}

	/**
	 * [forbid 封角色].
	 *
	 * @Author   王文凡
	 * @DateTime 2018-04-09
	 *
	 * @version  1.0
	 *
	 * @return [type] [description]
	 */
	public function forbid(Request $request) {
		$num = 0;
		$post = $request->post();
		$ids = $post['ids'];
		$delayTime = $post['exp_time'] ? strtotime($post['exp_time']) - time() : 0;
		$cause = $post['cause'];
		$now = Carbon::now()->toDateTimeString();
		$admin_name = \Auth::guard('admin')->user()->name;

		foreach ($ids as $id) {
			$player = PlayerGamedata::find($id);
			RequestService::playerKickOff($this->server_id, $player->name);
			$ret = RequestService::banRole($this->server_id, $id);
			if (!$ret) {
				++$num;
				Log::error('禁封角色失败:', $post);
			} else {
				//记录日志
				$time = $post['exp_time'] ? $post['exp_time'] : 0;
				DB::table('log_bans')->insert([
					'server_id' => $this->server_id,
					'player_id' => "{$player->id}",
					'player_name' => $player->name,
					'delay_time' => $time,
					'admin_name' => $admin_name,
					'client_ip' => $this->ip,
					'created_at' => $now,
					'updated_at' => $now,
				]);
			}
		}

		return ['status' => 0, 'message' => '执行成功!' . $num . '个失败'];
	}

	/**
	 * [banned 角色禁言].
	 *
	 * @Author   王文凡
	 * @DateTime 2018-04-10
	 *
	 * @version  1.0
	 *
	 * @param Request $request [description]
	 *
	 * @return
	 */
	public function banned(Request $request) {
		$post = $request->post();
		$time = $post['exp_time'] ? strtotime($post['exp_time']) : 0;
		$num = 0;
		$now = Carbon::now()->toDateTimeString();
		$admin_name = \Auth::guard('admin')->user()->name;
		foreach ($post['ids'] as $id) {
			$player = PlayerGamedata::find($id);
			$ret = RequestService::bannedRole($this->server_id, $player->name, $time, 1);
			if (!$ret) {
				++$num;
				Log::error('角色禁言失败:', $post);
			} else {
				//记录日志
				$exp_time = $post['exp_time'] ? $post['exp_time'] : 0;
				DB::table('log_banneds')->insert([
					'server_id' => $this->server_id,
					'player_id' => "{$player->id}",
					'player_name' => $player->name,
					'delay_time' => $exp_time,
					'admin_name' => $admin_name,
					'client_ip' => $this->ip,
					'created_at' => $now,
					'updated_at' => $now,
				]);
			}
		}

		return ['status' => 0, 'message' => '执行成功!' . $num . '个失败'];
	}

	//玩家状态日志记录
	public function record() {
		return Admin::content(function (Content $content) {
			$input = Input::all();
			switch ($input['type']) {
			case '0':
				//邮件日志
				$desc = '邮件';
				$table = $this->getEmail($input['id']);
				break;
			case '1':
				//背包物品
				$desc = '背包物品';
				$type = config('game.storageType.bag');
				$table = $this->getPack($input['id'], $type);
				break;
			case '2':
				//仓库物品
				$desc = '仓库物品';
				$type = config('game.storageType.warehouse');
				$table = $this->getPack($input['id'], $type);
				break;
			case '3':
				//装备物品
				$desc = '装备物品';
				// $type  = config('game.storageType.equip');
				$table = $this->equipment($input['id']);
				break;

			case '4':
				//道具变化
				$desc = '道具变化';
				$table = $this->getItemChange($input['id']);
				break;

			case '5':
				//体力变化
				$desc = '体力变化';
				$table = $this->getRefineChange($input['id'], config('game.moneyType.spirit'));
				break;
			case '6':
				//经验变化
				$desc = '经验变化';
				$table = $this->getExpChange($input['id']);
				break;
			case '8':
				//探矿仓库
				$desc = '探矿仓库';
				$type = config('game.storageType.explore');
				$table = $this->getPack($input['id'], $type);
				break;
			case '9':
				$desc = '金币变化';
				$table = $this->getRefineChange($input['player_id'], config('game.moneyType.coin'));
				break;
			case '10':
				$desc = '元宝变化';
				$table = $this->getRefineChange($input['player_id'], config('game.moneyType.gold'));
				break;
			case '11':
				$desc = '仙晶变化';
				$table = $this->getRefineChange($input['player_id'], config('game.moneyType.treasure'));
				break;
			case '12':
				$desc = '灵石变化';
				$table = $this->getRefineChange($input['player_id'], config('game.moneyType.stone'));
				break;
			case '13':
				$desc = '翅膀淬炼等级';
				$table = $this->wingsLevel($input['id']);
				break;
			case '14': //称号
				$desc = '玩家称号';
				$table = $this->titleList($input['id']);
			// no break
			default:
				// code...
				break;
			}

			$content->header('玩家相关');
			$content->description('角色日志--' . $desc);
			$box = $table->render();
			$content->body($box);
		});
	}

	private function titleList($id) {
		$list = PlayerService::getPlayerTitleList($id);
	}

	/**
	 * [getPack 玩家物品].
	 *
	 * @Author   王文凡
	 * @DateTime 2018-05-05
	 *
	 * @version  1.0
	 *
	 * @param int $id
	 * @param int $type
	 *
	 * @return Grid
	 */
	private function getPack($id, $type) {
		$grid = Admin::grid(Items::class, function (Grid $grid) use ($id, $type) {
			$grid->model()->where([['ownerID', '=', $id], ['storageType', '=', $type]]);
			$grid->id();
			$grid->ownerID('角色ID');
			$grid->itemDataID('物品ID');
			$grid->column('道具名称')->display(function () {
				$item = Item::find($this->itemDataID);

				return $item->name ?? '未知';
			});
			$grid->gridID('存储格子');
			$grid->layoutNum('堆叠数量');
			$grid->binded('是否绑定')->display(function ($binded) {
				return $binded ? '是' : '否';
			});
			$grid->param('幸运值');
			$grid->filter(function ($filter) {
				// 去掉默认的id过滤器
				$filter->disableIdFilter();
				$filter->setNotWhere(['type', 'id', 'serverid']);
				$filter->like('itemDataID', '物品ID');
			});
			$grid->disableActions();
			$grid->disableCreateButton();
			$grid->tools(function ($tools) {
				$tools->batch(function ($batch) {
					$batch->disableDelete();
				});
			});
		});

		return $grid;
	}

	/**
	 * [equipment 装备位置].
	 *
	 * @Author   王文凡
	 * @DateTime 2018-05-31
	 *
	 * @version  1.0
	 *
	 * @param int $id [玩家ID]
	 *
	 * @return Table
	 */
	private function equipment($id) {
		//获取装备
		$array = PlayerService::getPlayerEquipment($id);
		//装备位置名称
		$equipments = config('game.equipments');
		//4个神器
		$artifact = [12, 13, 14, 15];
		$headers = ['Id', '位置', '装备名称', '强化等级', '祝福等级', '宝石等级', '符文等级', '神器等级'];
		$array = array_slice($array, 0, 25);
		foreach ($array as $k => $eq) {
			if (in_array($k, [20, 21, 22, 23])) {
				continue;
			}
			//装备名称
			$items = Item::find($eq[1][2]);
			$name = $items ? $items->name : '无';
			//神器等级
			if (in_array($k, $artifact)) {
				$fact = 'undefined' == $eq[1] ? 0 : $name;
			} else {
				$fact = '无';
			}
			//定义符文宝石默认为空
			$rune_str = $gems_names = '';

			//符文属性
			if (is_array($eq[4])) {
				foreach ($eq[4] as $rune_data) {
					$runes = Item::find($rune_data[1]);
					$rune_str .= $runes->name . ':' . $rune_data[2] . ';';
				}
			}
			//宝石
			if (is_array($eq[5][4])) {
				$gem_ids = array_column($eq[5][4], 2);
				$gems = Item::whereIn('item_no', $gem_ids)->pluck('name')->toArray();
				if ($gems) {
					$gems_names = join(',', $gems);
				}
			}
			$row = [
				$k, $equipments[$k], $name, $eq[2], $eq[3], $gems_names, $rune_str, $fact,
			];
			$rows[] = $row;
		}

		$table = new Table($headers, $rows);

		return $table;
	}

	/**翅膀淬炼等级
		     * @param  integer $id [玩家ID]
		     * @return Table
	*/
	private function wingsLevel($id) {
		//获取装备
		$array = PlayerService::getPlayerEquipment($id);
		$data = array_slice($array, 25, 11);
		$rows = $row = [];
		foreach ($data as $key => $wings) {
			if (is_array($wings[1])) {
				//淬炼失败次数
				$full_numbers = $wings[2] % 1000;
				//淬炼等级
				$level = floor($wings[2] / 1000);
				$item_id = $wings[1][2];
				$item_data = Item::find($item_id);
				$name = $item_data ? $item_data->name : '无';
			} else {
				$name = '无';
				$full_numbers = $level = 0;
			}
			$row = [$key, $name, $level, $full_numbers];
			$rows[] = $row;
		}
		$headers = ['Id', '翅膀名称', '淬炼等级', '失败次数'];
		$table = new Table($headers, $rows);

		return $table;
	}

	/**
	 * [getEmail 玩家邮件列表].
	 *
	 * @Author   王文凡
	 * @DateTime 2018-05-05
	 *
	 * @version  1.0
	 *
	 * @return Grid
	 */
	private function getEmail($id) {
		$grid = Admin::grid(LogPlayerMail::class, function (Grid $grid) use ($id) {
			$grid->model()->where('mailReceivePlayerId', $id);
			$grid->mailId('ID');
			$grid->mailTitle('邮件标题');
			$grid->mailContent('邮件内容');
			$grid->mailSendName('发件人');
			$grid->mailSendtime('发送时间')->display(function ($time) {
				return date('Y-m-d H:i:s', $time);
			});
			$grid->mailReadState('读取状态')->display(function ($state) {
				return $state ? '已读' : '未读';
			});
			$grid->mailDeletetime('邮件状态')->display(function ($delete) {
				return $delete ? '删除' : '正常';
			});
			$grid->filter(function ($filter) {
				// 去掉默认的id过滤器
				$filter->disableIdFilter();
				$filter->setNotWhere();
			});
			$grid->disableActions();
			$grid->disableCreateButton();
			$grid->tools(function ($tools) {
				$tools->batch(function ($batch) {
					$batch->disableDelete();
				});
			});
		});

		return $grid;
	}

	/**
	 * [getItemChange 道具变化].
	 *
	 * @Author   王文凡
	 * @DateTime 2018-05-07
	 *
	 * @version  1.0
	 *
	 * @param [type] $id [玩家id]
	 *
	 * @return Grid
	 */
	private function getItemChange($id = null) {
		$grid = Admin::grid(LogItem::class, function (Grid $grid) use ($id) {
			//模糊搜索道具名
			$name = Input::get('name');

			if ($name) {
				$item_ids = Item::where('name', 'like', "%{$name}%")->pluck('item_no')->toArray();
				if (!empty($item_ids)) {
					$grid->model()->whereIn('itemDataID', $item_ids);
				}
			}
			if ($id) {
				$grid->model()->where('playerID', $id);
			}
			$time = Input::get('time');
			if ($time) {
				if (isset($time['start']) && $time['start']) {
					$grid->model()->where('time', '>=', strtotime($time['start']));
				}
				if (isset($time['end']) && $time['end']) {
					$grid->model()->where('time', '<=', strtotime($time['end']));
				}
			}

			$grid->playerID('玩家ID');
			$grid->itemDataID('道具ID');
			$grid->column('道具名称')->display(function () {
				$item = Item::find($this->itemDataID);

				return $item->name ?? '未知';
			});
			$grid->storageType('物品位置');
			$grid->oldGridID('原存储格子');
			$grid->newGridID('新存储格子');
			$grid->oldQuantity('原来数量');
			$grid->newQuantity('新的数量');
			$grid->reason('操作原因')->display(function ($reason) {
				$reason_data = StatEvent::where('event_id', '=', $reason)->first();

				return $reason_data->name ?? '未知';
			});
			$grid->time('操作时间')->display(function ($time) {
				return date('Y-m-d H:i:s', $time);
			})->sortable();
			$grid->filter(function ($filter) {
				// 去掉默认的id过滤器
				$filter->disableIdFilter();
				$filter->equal('name', '道具名称');
				$filter->between('time', '变化日期')->date();
				$filter->setNotWhere(['name', 'time']);
			});
			$grid->disableActions();
			$grid->disableCreateButton();
			$grid->tools(function ($tools) {
				$tools->batch(function ($batch) {
					$batch->disableDelete();
				});
			});
		});

		return $grid;
	}

	/**
	 * [getRefineChange 玩家物品变化].
	 *
	 * @Author   王文凡
	 * @DateTime 2018-05-07
	 *
	 * @version  1.0
	 *
	 * @param [type] $id [description]
	 *
	 * @return Grid
	 */
	private function getRefineChange($id, $type) {
		$grid = Admin::grid(LogMoneyChange::class, function (Grid $grid) use ($id, $type) {
			$grid->model()->where('playerid', $id)->where('moneytype', $type);

			$grid->playerid('角色ID');
			$grid->moneytype('类型');
			$grid->changeCount('改变数量');
			$grid->oldMoney('原来数量');
			$grid->newMoney('新的数量');
			$grid->changetype('操作原因')->display(function ($id) {
				$reason = StatEvent::where('event_id', $id)->first();

				return $reason ? $reason->name : '无';
			});
			$grid->time('操作时间')->display(function ($time) {
				return date('Y-m-d H:i:s', $time);
			})->sortable();
			$grid->filter(function ($filter) {
				// 去掉默认的id过滤器
				$filter->disableIdFilter();
				$filter->setNotWhere();
			});
			$grid->disableActions();
			$grid->disableCreateButton();
			$grid->tools(function ($tools) {
				$tools->batch(function ($batch) {
					$batch->disableDelete();
				});
			});
		});

		return $grid;
	}

	/**
	 * [getExpChange 玩家经验变化].
	 *
	 * @Author   王文凡
	 * @DateTime 2018-05-07
	 *
	 * @version  1.0
	 *
	 * @param [type] $id [description]
	 *
	 * @return Grid
	 */
	private function getExpChange($id) {
		$grid = Admin::grid(LogExpChange::class, function (Grid $grid) use ($id) {
			$grid->model()->where('playerid', $id);
			$grid->playerid('角色ID');
			$grid->level('等级');
			$grid->exp('经验');
			$grid->changeCount('变化数量');
			$grid->changetype('操作原因')->display(function ($type) {
				$reason = StatEvent::where('event_id', $type)->first();

				return $reason ? $reason->name : '无';
			});
			$grid->param('杀怪数量或bossid');
			$grid->time('操作时间')->display(function ($time) {
				return date('Y-m-d H:i:s', $time);
			})->sortable();
			$grid->filter(function ($filter) {
				// 去掉默认的id过滤器
				$filter->disableIdFilter();
				$filter->setNotWhere();
			});
			$grid->disableActions();
			$grid->disableCreateButton();
			$grid->tools(function ($tools) {
				$tools->batch(function ($batch) {
					$batch->disableDelete();
				});
			});
		});

		return $grid;
	}
}
